//==========================================================================
// Copyright (c) 2000-2008,  Elastos, Inc.  All Rights Reserved.
//==========================================================================
#include "gpio.h"

void xs_setgpio_dir(int gpio_num, int direction)
{
    volatile int *regT;

    if (gpio_num < 32) {
        regT = (volatile int *)GPDR0;
        if (direction == GPIO_PIN_IN)
            *regT &= ~(1 << (gpio_num % 32));
        if (direction == GPIO_PIN_OUT)
            *regT |= (1 << (gpio_num % 32));
        return;
    }
    if (gpio_num < 64) {
        regT = (volatile int *)GPDR1;
        if (direction == GPIO_PIN_IN)
            *regT &= ~(1 << (gpio_num % 32));
        if (direction == GPIO_PIN_OUT)
            *regT |= (1 << (gpio_num % 32));
        return;
    }
    if (gpio_num < 96) {
        regT = (volatile int *)GPDR2;
        if (direction == GPIO_PIN_IN)
            *regT &= ~(1 << (gpio_num % 32));
        if (direction == GPIO_PIN_OUT)
            *regT |= (1 << (gpio_num % 32));
        return;
    }
    if (gpio_num <= 120) {
        regT = (volatile int *)GPDR3;
        if (direction == GPIO_PIN_IN)
            *regT &= ~(1 << (gpio_num % 32));
        if (direction == GPIO_PIN_OUT)
            *regT |= (1 << (gpio_num % 32));
        return;
    }
}
void xs_setgpio_outhigh(int gpio_num)
{
    volatile int *regT;

    if (gpio_num < 32) {
        regT = (volatile int *)GPSR0;
        *regT |= (1 << (gpio_num % 32));
        return;
    }
    if (gpio_num < 64) {
        regT = (volatile int *)GPSR1;
        *regT |= (1 << (gpio_num % 32));
        return;
    }
    if (gpio_num < 96) {
        regT = (volatile int *)GPSR2;
        *regT |= (1 << (gpio_num % 32));
        return;
    }
    if (gpio_num <= 120) {
        regT = (volatile int *)GPSR3;
        *regT |= (1 << (gpio_num % 32));
        return;
    }
}
void xs_setgpio_outlow(int gpio_num)
{
    volatile int *regT;

    if (gpio_num < 32) {
        regT = (volatile int *)GPCR0;
        *regT |= (1 << (gpio_num % 32));
        return;
    }
    if (gpio_num < 64) {
        regT = (volatile int *)GPCR1;
        *regT |= (1 << (gpio_num % 32));
        return;
    }
    if (gpio_num < 96) {
        regT = (volatile int *)GPCR2;
        *regT |= (1 << (gpio_num % 32));
        return;
    }
    if (gpio_num <= 120) {
        regT = (volatile int *)GPCR3;
        *regT |= (1 << (gpio_num % 32));
        return;
    }
}
void xs_setgpio_RER(int gpio_num, int isedge)
{
    volatile int *regT;

    if (gpio_num < 32) {
        regT = (volatile int *)GRER0;
        if (isedge == DISABLE_EDGE)
            *regT &= ~(1 << (gpio_num % 32));
        if (isedge == ENABLE_EDGE)
            *regT |= (1 << (gpio_num % 32));
        return;
    }
    if (gpio_num < 64) {
        regT = (volatile int *)GRER1;
        if (isedge == DISABLE_EDGE)
            *regT &= ~(1 << (gpio_num % 32));
        if (isedge == ENABLE_EDGE)
            *regT |= (1 << (gpio_num % 32));
        return;
    }
    if (gpio_num < 96) {
        regT = (volatile int *)GRER2;
        if (isedge == DISABLE_EDGE)
            *regT &= ~(1 << (gpio_num % 32));
        if (isedge == ENABLE_EDGE)
            *regT |= (1 << (gpio_num % 32));
        return;
    }
    if (gpio_num <= 120) {
        regT = (volatile int *)GRER3;
        if (isedge == DISABLE_EDGE)
            *regT &= ~(1 << (gpio_num % 32));
        if (isedge == ENABLE_EDGE)
            *regT |= (1 << (gpio_num % 32));
        return;
    }
}
void xs_setgpio_FER(int gpio_num, int isedge)
{
    volatile int *regT;

    if (gpio_num < 32) {
        regT = (volatile int *)GFER0;
        if (isedge == DISABLE_EDGE)
            *regT &= ~(1 << (gpio_num % 32));
        if (isedge == ENABLE_EDGE)
            *regT |= (1 << (gpio_num % 32));
        return;
    }
    if (gpio_num < 64) {
        regT = (volatile int *)GFER1;
        if (isedge == DISABLE_EDGE)
            *regT &= ~(1 << (gpio_num % 32));
        if (isedge == ENABLE_EDGE)
            *regT |= (1 << (gpio_num % 32));
        return;
    }
    if (gpio_num < 96) {
        regT = (volatile int *)GFER2;
        if (isedge == DISABLE_EDGE)
            *regT &= ~(1 << (gpio_num % 32));
        if (isedge == ENABLE_EDGE)
            *regT |= (1 << (gpio_num % 32));
        return;
    }
    if (gpio_num <= 120) {
        regT = (volatile int *)GFER3;
        if (isedge == DISABLE_EDGE)
            *regT &= ~(1 << (gpio_num % 32));
        if (isedge == ENABLE_EDGE)
            *regT |= (1 << (gpio_num % 32));
        return;
    }
}
void xs_setgpio_AFR(int gpio_num, int function)
{
    volatile int *regT;

    if (gpio_num < 16) {
        regT = (volatile int *)GAFR0_L;
        if (function == GPIO_AS_GPIO) {

            *regT &= ~((1 << ((gpio_num % 16) * 2))
                    | (1 << ((gpio_num % 16) * 2 + 1)));
            //*regT |= (11 << ((gpio_num % 16) * 2));
        }
        if (function == GPIO_AS_AF1) {

            *regT &= ~(1 << ((gpio_num % 16) * 2 + 1));
            *regT |= (1 << ((gpio_num % 16) * 2));
        }
        if (function == GPIO_AS_AF2) {

            *regT &= ~(1 << ((gpio_num % 16) * 2));
            *regT |= (1 << ((gpio_num % 16) * 2 + 1));
        }
        if (function == GPIO_AS_AF3) {

            //*regT &= ~(11 << ((gpio_num % 16) * 2));
            *regT |= ((1 << ((gpio_num % 16) * 2))
                    | (1 << ((gpio_num % 16) * 2 + 1)));
        }
        return;
    }
    if (gpio_num < 32) {
        regT = (volatile int *)GAFR0_H;
        if (function == GPIO_AS_GPIO) {

            *regT &= ~((1 << ((gpio_num % 16) * 2))
                    | (1 << ((gpio_num % 16) * 2 + 1)));
            //*regT |= (11 << ((gpio_num % 16) * 2));
        }
        if (function == GPIO_AS_AF1) {

            *regT &= ~(1 << ((gpio_num % 16) * 2 + 1));
            *regT |= (1 << ((gpio_num % 16) * 2));
        }
        if (function == GPIO_AS_AF2) {

            *regT &= ~(1 << ((gpio_num % 16) * 2));
            *regT |= (1 << ((gpio_num % 16) * 2 + 1));
        }
        if (function == GPIO_AS_AF3) {

            //*regT &= ~(11 << ((gpio_num % 16) * 2));
            *regT |= ((1 << ((gpio_num % 16) * 2))
                    | (1 << ((gpio_num % 16) * 2 + 1)));
        }
        return;
    }
    if (gpio_num < 48) {
        regT = (volatile int *)GAFR1_L;
        if (function == GPIO_AS_GPIO) {

            *regT &= ~((1 << ((gpio_num % 16) * 2))
                    | (1 << ((gpio_num % 16) * 2 + 1)));
            //*regT |= (11 << ((gpio_num % 16) * 2));
        }
        if (function == GPIO_AS_AF1) {

            *regT &= ~(1 << ((gpio_num % 16) * 2 + 1));
            *regT |= (1 << ((gpio_num % 16) * 2));
        }
        if (function == GPIO_AS_AF2) {

            *regT &= ~(1 << ((gpio_num % 16) * 2));
            *regT |= (1 << ((gpio_num % 16) * 2 + 1));
        }
        if (function == GPIO_AS_AF3) {

            //*regT &= ~(11 << ((gpio_num % 16) * 2));
            *regT |= ((1 << ((gpio_num % 16) * 2))
                    | (1 << ((gpio_num % 16) * 2 + 1)));
        }
        return;
    }
    if (gpio_num < 64) {
        regT = (volatile int *)GAFR1_H;
        if (function == GPIO_AS_GPIO) {

            *regT &= ~((1 << ((gpio_num % 16) * 2))
                    | (1 << ((gpio_num % 16) * 2 + 1)));
            //*regT |= (11 << ((gpio_num % 16) * 2));
        }
        if (function == GPIO_AS_AF1) {

            *regT &= ~(1 << ((gpio_num % 16) * 2 + 1));
            *regT |= (1 << ((gpio_num % 16) * 2));
        }
        if (function == GPIO_AS_AF2) {

            *regT &= ~(1 << ((gpio_num % 16) * 2));
            *regT |= (1 << ((gpio_num % 16) * 2 + 1));
        }
        if (function == GPIO_AS_AF3) {

            //*regT &= ~(11 << ((gpio_num % 16) * 2));
            *regT |= ((1 << ((gpio_num % 16) * 2))
                    | (1 << ((gpio_num % 16) * 2 + 1)));
        }
        return;
    }
    if (gpio_num < 80) {
        regT = (volatile int *)GAFR2_L;
        if (function == GPIO_AS_GPIO) {

            *regT &= ~((1 << ((gpio_num % 16) * 2))
                    | (1 << ((gpio_num % 16) * 2 + 1)));
            //*regT |= (11 << ((gpio_num % 16) * 2));
        }
        if (function == GPIO_AS_AF1) {

            *regT &= ~(1 << ((gpio_num % 16) * 2 + 1));
            *regT |= (1 << ((gpio_num % 16) * 2));
        }
        if (function == GPIO_AS_AF2) {

            *regT &= ~(1 << ((gpio_num % 16) * 2));
            *regT |= (1 << ((gpio_num % 16) * 2 + 1));
        }
        if (function == GPIO_AS_AF3) {

            //*regT &= ~(11 << ((gpio_num % 16) * 2));
            *regT |= ((1 << ((gpio_num % 16) * 2))
                    | (1 << ((gpio_num % 16) * 2 + 1)));
        }
        return;
    }
    if (gpio_num < 96) {
        regT = (volatile int *)GAFR2_H;
        if (function == GPIO_AS_GPIO) {

            *regT &= ~((1 << ((gpio_num % 16) * 2))
                    | (1 << ((gpio_num % 16) * 2 + 1)));
            //*regT |= (11 << ((gpio_num % 16) * 2));
        }
        if (function == GPIO_AS_AF1) {

            *regT &= ~(1 << ((gpio_num % 16) * 2 + 1));
            *regT |= (1 << ((gpio_num % 16) * 2));
        }
        if (function == GPIO_AS_AF2) {

            *regT &= ~(1 << ((gpio_num % 16) * 2));
            *regT |= (1 << ((gpio_num % 16) * 2 + 1));
        }
        if (function == GPIO_AS_AF3) {

            //*regT &= ~(11 << ((gpio_num % 16) * 2));
            *regT |= ((1 << ((gpio_num % 16) * 2))
                    | (1 << ((gpio_num % 16) * 2 + 1)));
        }
        return;
    }
    if (gpio_num < 112) {
        regT = (volatile int *)GAFR3_L;
        if (function == GPIO_AS_GPIO) {

            *regT &= ~((1 << ((gpio_num % 16) * 2))
                    | (1 << ((gpio_num % 16) * 2 + 1)));
            //*regT |= (11 << ((gpio_num % 16) * 2));
        }
        if (function == GPIO_AS_AF1) {

            *regT &= ~(1 << ((gpio_num % 16) * 2 + 1));
            *regT |= (1 << ((gpio_num % 16) * 2));
        }
        if (function == GPIO_AS_AF2) {

            *regT &= ~(1 << ((gpio_num % 16) * 2));
            *regT |= (1 << ((gpio_num % 16) * 2 + 1));
        }
        if (function == GPIO_AS_AF3) {

            //*regT &= ~(11 << ((gpio_num % 16) * 2));
            *regT |= ((1 << ((gpio_num % 16) * 2))
                    | (1 << ((gpio_num % 16) * 2 + 1)));
        }
        return;
    }
    if (gpio_num <= 120) {
        regT = (volatile int *)GAFR3_H;
        if (function == GPIO_AS_GPIO) {

            *regT &= ~((1 << ((gpio_num % 16) * 2))
                    | (1 << ((gpio_num % 16) * 2 + 1)));
            //*regT |= (11 << ((gpio_num % 16) * 2));
        }
        if (function == GPIO_AS_AF1) {

            *regT &= ~(1 << ((gpio_num % 16) * 2 + 1));
            *regT |= (1 << ((gpio_num % 16) * 2));
        }
        if (function == GPIO_AS_AF2) {

            *regT &= ~(1 << ((gpio_num % 16) * 2));
            *regT |= (1 << ((gpio_num % 16) * 2 + 1));
        }
        if (function == GPIO_AS_AF3) {

            //*regT &= ~(11 << ((gpio_num % 16) * 2));
            *regT |= ((1 << ((gpio_num % 16) * 2))
                    | (1 << ((gpio_num % 16) * 2 + 1)));
        }
        return;
    }
}
void xs_clrgpio_EDR(int gpio_num)
{
    volatile int *regT;

    if (gpio_num < 32) {
        regT = (volatile int *)GEDR0;
        *regT |= (1 << (gpio_num % 32));
        return;
    }
    if (gpio_num < 64) {
        regT = (volatile int *)GEDR1;
        *regT |= (1 << (gpio_num % 32));
        return;
    }
    if (gpio_num < 96) {
        regT = (volatile int *)GEDR2;
        *regT |= (1 << (gpio_num % 32));
        return;
    }
    if (gpio_num <= 120) {
        regT = (volatile int *)GEDR3;
        *regT |= (1 << (gpio_num % 32));
        return;
    }
}

int xs_getgpio_inLEV(int gpio_num)
{
    volatile int *regT;

    if (gpio_num < 32) {
        regT = (volatile int *)GPLR0;
        if (*regT & (1 << (gpio_num % 32)))
            return GPIO_HIGH;
        else
            return GPIO_LOW;
    }
    if (gpio_num < 64) {
        regT = (volatile int *)GPLR1;
        if (*regT & (1 << (gpio_num % 32)))
            return GPIO_HIGH;
        else
            return GPIO_LOW;
    }
    if (gpio_num < 96) {
        regT = (volatile int *)GPLR2;
        if (*regT & (1 << (gpio_num % 32)))
            return GPIO_HIGH;
        else
            return GPIO_LOW;
    }
    if (gpio_num <= 120) {
        regT = (volatile int *)GPLR3;
        if (*regT & (1 << (gpio_num % 32)))
            return GPIO_HIGH;
        else
            return GPIO_LOW;
    }
    return 0;
}
int xs_getgpio_EDR(int gpio_num)
{
    volatile int *regT;

    if (gpio_num < 32) {
        regT = (volatile int *)GEDR0;
        if (*regT & (1 << (gpio_num % 32)))
            return GPIO_EDGE;
        else
            return GPIO_NOEDGE;
    }
    if (gpio_num < 64) {
        regT = (volatile int *)GEDR1;
        if (*regT & (1 << (gpio_num % 32)))
            return GPIO_EDGE;
        else
            return GPIO_NOEDGE;
    }
    if (gpio_num < 96) {
        regT = (volatile int *)GEDR2;
        if (*regT & (1 << (gpio_num % 32)))
            return GPIO_EDGE;
        else
            return GPIO_NOEDGE;
    }
    if (gpio_num <= 120) {
        regT = (volatile int *)GEDR3;
        if (*regT & (1 << (gpio_num % 32)))
            return GPIO_EDGE;
        else
            return GPIO_NOEDGE;
    }
    return 0;
}
